package com.my.xq.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.my.wechat.controller.WxTemplateMesController;
import com.my.wechat.domain.WeChatMenuJQTreeNode;
import com.my.wechat.domain.entity.WeChatMenuEntity;
import com.my.xq.domain.DoorplateListOrderQueryParam;
import com.my.xq.domain.DoorplateQueryParam;
import com.my.xq.domain.VoteParam;
import com.my.xq.domain.YwhSettingsJQTreeNode;
import com.my.xq.domain.entity.Court;
import com.my.xq.domain.entity.CourtRole;
import com.my.xq.domain.entity.CourtRole_Proprietor;
import com.my.xq.domain.entity.CourtYwhSettings;
import com.my.xq.domain.entity.Doorplate;
import com.my.xq.domain.entity.Proprietor;
import com.my.xq.domain.entity.RenWu;
import com.my.xq.domain.entity.RenWuCreate;
import com.my.xq.domain.entity.RenWuDefine;
import com.my.xq.domain.vo.CourtVO;
import com.my.xq.domain.vo.DoorCount;
import com.my.xq.domain.vo.DoorInfo;
import com.my.xq.domain.vo.DoorVO;
import com.my.xq.domain.vo.YwhVoteResultInfo;
import com.my.xq.repository.CourtRepository;
import com.my.xq.repository.CourtRoleBindRepository;
import com.my.xq.repository.CourtRoleRepository;
import com.my.xq.repository.CourtYwhSettingsRepository;
import com.my.xq.repository.DoorplateRepository;
import com.my.xq.repository.ProprietorRepository;
import com.my.xq.repository.RenWuCreateRepository;
import com.my.xq.repository.RenWuRepository;
import com.sskj.common.tree.TreeNode;
import com.sskj.common.tree.TreeUtil;
import com.sskj.common.util.CalendarUtil;
import com.sskj.core.annotation.ControllerLogExeTime;
import com.sskj.core.exception.MException;
import com.sskj.sys.repository.MediaRepository;

import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import springfox.documentation.annotations.ApiIgnore;

@RestController
@RequestMapping("/mp")
public class DoorplateServiceImpl {
	@Autowired
	DoorplateRepository doorplateRepository;

	@Autowired
	ProprietorRepository proprietorRepository;

	@Autowired
	MediaRepository mediaRepository;

	@Autowired
	CourtRepository courtRepository;

	@Autowired
	RenWuRepository rwRepository;

	@Autowired
	RenWuCreateRepository rwCreateRepository;

	@Autowired
	CourtRoleRepository courtRoleRepository;

	@Autowired
	CourtRoleBindRepository courtRoleBindRepository;

	@Autowired
	CourtYwhSettingsRepository courtYwhSettingsRepository;

	@Autowired
	private WxMpService wxService;

	@Value(value = "${wechat.mp.voteTempleteCode}")
	private String voteTempleteCode;

	@Value(value = "${sskj.conf.webDomain}")
	private String webDomain;

	private final Logger logger = LoggerFactory.getLogger(this.getClass());

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/addmpInfo", method = { RequestMethod.POST })
	@ControllerLogExeTime(description = "添加门牌信息")
	public void addmpInfo(Doorplate p) {
		if (null == p.getId() || "".equals(p.getId())) {
			doorplateRepository.save(p);
		} else {
			Doorplate d = doorplateRepository.get(p.getId());
			d.setDoorplateNo(p.getDoorplateNo());
			d.setUnit(p.getUnit());
			d.setBuilding(p.getBuilding());
			doorplateRepository.save(d);
		}
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/findAll", method = { RequestMethod.GET })
	@ControllerLogExeTime(description = "查询门牌信息")
	@ApiOperation(value = "查询小区信息", httpMethod = "GET")
	@ApiImplicitParams({ @ApiImplicitParam(name = "pageNumber", value = "页号", paramType = "form", dataType = "int"),
			@ApiImplicitParam(name = "pageSize", value = "页的大小", paramType = "form", dataType = "int") })
	public Page<Doorplate> findAllPage(Doorplate d, @ApiIgnore Pageable pageable, HttpServletRequest request) {
		Page<Doorplate> page = doorplateRepository.findByProprietorName(d.getProprietorName(), pageable);
		List<Doorplate> list = page.getContent();
		for (int i = 0; i < list.size(); i++) {
			Doorplate dp = list.get(i);
			String proprietorId = dp.getProprietorId();
			String courtId = dp.getCourtId();
			if (null != proprietorId) {
				dp.setProprietorName(proprietorRepository.get(proprietorId).getName());
			}
			if (null != courtId) {
				dp.setCourtName(courtRepository.get(courtId).getName());
			}
		}
		return page;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "查询一条门牌记录", log = false)
	@RequestMapping(value = "/findOne", method = { RequestMethod.GET })
	public Doorplate findOne(String id, HttpServletRequest request) {
		Doorplate doorplate = doorplateRepository.get(id);
		return doorplate;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "根据小区查询所有的门牌号", log = false)
	@RequestMapping(value = "/findDoorplateByxq", method = { RequestMethod.GET })
	@ApiImplicitParams({ @ApiImplicitParam(name = "courtId", value = "小区id", paramType = "form", dataType = "string"),
			@ApiImplicitParam(name = "pageNumber", value = "页号", paramType = "form", dataType = "int"),
			@ApiImplicitParam(name = "pageSize", value = "页的大小", paramType = "form", dataType = "int") })
	public Page<Doorplate> findDoorplateByxq(DoorplateListOrderQueryParam param, @ApiIgnore Pageable pageable,
			HttpServletRequest request) {
		Page<Doorplate> page = doorplateRepository.findPage(param, pageable);
		List<Doorplate> list = page.getContent();
		for (int i = 0; i < list.size(); i++) {
			Doorplate dp = list.get(i);
			String proprietorId = dp.getProprietorId();
			if (null != proprietorId) {
				Proprietor p = proprietorRepository.get(proprietorId);
				if (p != null) {
					dp.setProprietorName(p.getName());
				}
			}
		}
		return page;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "删除门牌信息", log = false)
	@RequestMapping(value = "/delmpInfo", method = { RequestMethod.POST })
	public void delmpInfo(String id) {
		doorplateRepository.delete(id);
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "根据选取小区和指定门牌号进行查询", log = false)
	@RequestMapping(value = "/searchDoorPlate", method = { RequestMethod.GET })
	public List<Doorplate> searchDoorPlate(Doorplate doorplate) {
		List<Doorplate> list = doorplateRepository.searchDoorPlate(doorplate.getDoorplateNo(),
				this.toList(doorplate.getCourtId().isEmpty() ? "XXXXX" : doorplate.getCourtId(), ","));
		return list;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "绑定业主", log = false)
	@RequestMapping(value = "/bindProprietor", method = { RequestMethod.POST })
	public void bindProprietor(String proprietorId, String ids) {
		// 首先解绑该业主所有的绑定门牌号，再重新进行绑定
		doorplateRepository.unbindProprietor(proprietorId);
		Proprietor p = proprietorRepository.get(proprietorId);
		doorplateRepository.bindProprietor(proprietorId, toList(ids, ","), p.getOpenid());
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "解绑业主", log = false)
	@RequestMapping(value = "/unbindProprietor", method = { RequestMethod.POST })
	public void unbindProprietor(Doorplate doorplate) {
		doorplateRepository.unbindProprietor(doorplate.getProprietorId());
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "根据所给业主获取绑定门牌号信息", log = false)
	@RequestMapping(value = "/loadBindDoorplate", method = { RequestMethod.GET })
	public List<Doorplate> loadBindDoorplate(Doorplate doorplate) {
		return doorplateRepository.loadBindDoorplate(doorplate.getProprietorId());
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "根据所给业主获取绑定和授权的门牌号信息", log = false)
	@RequestMapping(value = "/loadDoorplateIncludeAuth", method = { RequestMethod.GET })
	public List<Doorplate> loadDoorplateIncludeAuth(Doorplate doorplate) {
		return doorplateRepository.loadDoorplateIncludeAuth(doorplate.getProprietorId());
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/ywh/vote/role", method = { RequestMethod.GET })
	@ApiOperation(value = "查询门牌号是否有投票权", notes = "查询门牌号是否有投票权", httpMethod = "GET")
	public boolean hasYwhVoteRole(String proprietorId, String courtId, String building, String unit, String rwCode) {
		if ("CAST01".equals(rwCode)) {
			List<Doorplate> doors = doorplateRepository.getCanVoteDoorplateUnit(proprietorId, courtId, building, unit);
			return !(doors == null || doors.isEmpty());
		} else if ("CAST02".equals(rwCode)) {
			List<Doorplate> doors = doorplateRepository.getCanVoteDoorplateBuilding(proprietorId, courtId, building);
			return !(doors == null || doors.isEmpty());
		} else if ("CAST03".equals(rwCode)) {
			List<Doorplate> doors = doorplateRepository.getCanVoteDoorplateMember(proprietorId, courtId);
			return !(doors == null || doors.isEmpty());
		} else if ("CAST04".equals(rwCode)) {
			List<Doorplate> doors = doorplateRepository.getCanVoteDoorplateHead(proprietorId, courtId);
			return !(doors == null || doors.isEmpty());
		} else {
			return false;
		}
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/ywh/isVoted", method = { RequestMethod.GET })
	@ApiOperation(value = "查询门牌号是否已经投票", notes = "查询门牌号是否已经投票", httpMethod = "GET")
	public YwhVoteResultInfo isVoted(String proprietorId, String courtId, String building, String unit, String rwCode) {
		YwhVoteResultInfo rtn = new YwhVoteResultInfo();
		List<Doorplate> doors;
		if ("CAST01".equals(rwCode)) {
			doors = doorplateRepository.getIsVoteDoorplateUnit(proprietorId, courtId, building, unit);
			for (Doorplate d : doors) {
				if (d.isRightUnit()) {
					rtn.setVoted(true);
					rtn.setVotedDoorId(d.getUnitVoteDoorplateId());
					break;
				}
			}
		} else if ("CAST02".equals(rwCode)) {
			doors = doorplateRepository.getIsVoteDoorplateBuilding(proprietorId, courtId, building);
			for (Doorplate d : doors) {
				if (d.isRightBuilding()) {
					rtn.setVoted(true);
					rtn.setVotedDoorId(d.getBuildingVoteDoorplateId());
					break;
				}
			}
		} else if ("CAST03".equals(rwCode)) {
			doors = doorplateRepository.getIsVoteDoorplateMember(proprietorId, courtId);
			for (Doorplate d : doors) {
				if (d.isRightMember()) {
					rtn.setVoted(true);
					rtn.setVotedDoorId(d.getMemberVoteDoorplateId());
					break;
				}
			}
		} else if ("CAST04".equals(rwCode)) {
			doors = doorplateRepository.getIsVoteDoorplateHead(proprietorId, courtId);
			for (Doorplate d : doors) {
				if (d.isRightHead()) {
					rtn.setVoted(true);
					rtn.setVotedDoorId(d.getHeadVoteDoorplateId());
					break;
				}
			}
		} else {
			logger.info("没有任务：rwCode=[" + rwCode + "]");
		}
		return rtn;
	}

	/**
	 * 
	 * @param votedDoorId
	 *            被投票的门牌号
	 * @param proprietorId
	 *            投票人ID
	 * @param courtId
	 *            小区ID
	 * @param building
	 *            楼栋号
	 * @param unit
	 * @param rwCode
	 * @return
	 */
	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/ywh/vote", method = { RequestMethod.POST })
	@ApiOperation(value = "业委会选举投票（所有门牌一起投）", notes = "业委会选举投票（所有门牌一起投）", httpMethod = "POST")
	public boolean doYwhVote(String votedDoorId, String proprietorId, String rwCode) {
		Doorplate door = doorplateRepository.get(votedDoorId);
		if (door == null) {
			return false;
		}
		List<Doorplate> doors;
		if ("CAST01".equals(rwCode)) {
			doors = doorplateRepository.getCanVoteDoorplateUnit(proprietorId, door.getCourtId(), door.getBuilding(),
					door.getUnit());
			if (doors == null || doors.isEmpty()) {
				return false;
			}
			int count = door.getCountUnit();
			door.setCountUnit(doors.size() + count);
		} else if ("CAST02".equals(rwCode)) {
			doors = doorplateRepository.getCanVoteDoorplateBuilding(proprietorId, door.getCourtId(),
					door.getBuilding());
			if (doors == null || doors.isEmpty()) {
				return false;
			}
			int count = door.getCountBuilding();
			door.setCountBuilding(doors.size() + count);
		} else if ("CAST03".equals(rwCode)) {
			doors = doorplateRepository.getCanVoteDoorplateMember(proprietorId, door.getCourtId());
			if (doors == null || doors.isEmpty()) {
				return false;
			}
			int count = door.getCountMember();
			door.setCountMember(doors.size() + count);
		} else if ("CAST04".equals(rwCode)) {
			doors = doorplateRepository.getCanVoteDoorplateHead(proprietorId, door.getCourtId());
			if (doors == null || doors.isEmpty()) {
				return false;
			}
			int count = door.getCountHead();
			door.setCountHead(doors.size() + count);
		} else {
			return false;
		}

		doorplateRepository.save(door);
		for (Doorplate d : doors) {
			setRight(d, rwCode, votedDoorId);
		}
		return true;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/castunitadd", method = { RequestMethod.POST })
	@ApiOperation(value = "投票计数", notes = "投票计数", httpMethod = "POST")
	public Doorplate castUnitAdd(@RequestBody VoteParam o) throws MException {
		Doorplate d = doorplateRepository.get(o.getDoorId());
		Doorplate r = doorplateRepository.get(o.getSelfDoorplateid());
		String renWuDefine = "";
		int count = 0;
		if (d != null && r != null) {
			if (o.getRwCode().equals(RenWuDefine.CAST01.toString())) {
				count = d.getCountUnit();
				renWuDefine = RenWuDefine.CAST01.toString();
				count += 1;
				d.setCountUnit(count);
			}
			if (o.getRwCode().equals(RenWuDefine.CAST02.toString())) {
				count = d.getCountBuilding();
				renWuDefine = RenWuDefine.CAST02.toString();
				count += 1;
				d.setCountBuilding(count);
			}
			if (o.getRwCode().equals(RenWuDefine.CAST03.toString())) {
				count = d.getCountMember();
				renWuDefine = RenWuDefine.CAST03.toString();
				count += 1;
				d.setCountMember(count);
			}
			if (o.getRwCode().equals(RenWuDefine.CAST04.toString())) {
				count = d.getCountHead();
				renWuDefine = RenWuDefine.CAST04.toString();
				count += 1;
				d.setCountHead(count);
			}
			doorplateRepository.save(d);
			setRight(r, renWuDefine, o.getDoorId());
		} else {
			logger.error("获取投票人或者投给的人的门牌号信息发生错误");
		}
		return d;
	}

	public void setRight(Doorplate r, String rwCode, String voteDoorplateId) {
		if (rwCode.equals(RenWuDefine.CAST01.toString())) {
			r.setRightUnit(true);
			r.setUnitVoteDoorplateId(voteDoorplateId);
		}
		if (rwCode.equals(RenWuDefine.CAST02.toString())) {
			r.setRightBuilding(true);
			r.setBuildingVoteDoorplateId(voteDoorplateId);
		}
		if (rwCode.equals(RenWuDefine.CAST03.toString())) {
			r.setRightMember(true);
			r.setMemberVoteDoorplateId(voteDoorplateId);
		}
		if (rwCode.equals(RenWuDefine.CAST04.toString())) {
			r.setRightHead(true);
			r.setHeadVoteDoorplateId(voteDoorplateId);
		}
		doorplateRepository.save(r);
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping("/findRight")
	@ApiOperation(value = "获取投票权限", notes = "获取投票权限", httpMethod = "GET")
	@ApiImplicitParams({
			@ApiImplicitParam(name = "courtId", value = "courtId", paramType = "form", dataType = "string"),
			@ApiImplicitParam(name = "propriId", value = "propriId", paramType = "form", dataType = "string"),
			@ApiImplicitParam(name = "building", value = "building", paramType = "form", dataType = "string"),
			@ApiImplicitParam(name = "unit", value = "unit", paramType = "form", dataType = "string"),
			@ApiImplicitParam(name = "rwCode", value = "rwCode", paramType = "form", dataType = "string") })
	public Doorplate findRight(@ApiIgnore VoteParam p) {
		Doorplate r = null;
		if (StringUtils.isNotEmpty(p.getRwCode())) {
			if (p.getRwCode().equals(RenWuDefine.CAST01.toString())) {
				List<Doorplate> rs = doorplateRepository.LoadDoorPriproCast(p.getCourtId(), p.getPropriId(),
						p.getBuilding(), p.getUnit());
				if (null != rs && rs.isEmpty()) {
					r = rs.get(0);
				}
			}
			if (p.getRwCode().equals(RenWuDefine.CAST02.toString())) {
				List<Doorplate> rs = doorplateRepository.LoadDoorPriproCast(p.getCourtId(), p.getPropriId(),
						p.getBuilding());
				if (null != rs && rs.isEmpty()) {
					r = rs.get(0);
				}
			}
			if (p.getRwCode().equals(RenWuDefine.CAST03.toString())) {
				List<Doorplate> rs = doorplateRepository.LoadDoorPriproCast(p.getCourtId(), p.getPropriId());
				if (null != rs && rs.isEmpty()) {
					r = rs.get(0);
				}
			}
			if (p.getRwCode().equals(RenWuDefine.CAST04.toString())) {
				List<Doorplate> rs = doorplateRepository.LoadDoorPriproCast(p.getCourtId(), p.getPropriId());
				if (null != rs && rs.isEmpty()) {
					r = rs.get(0);
				}
			}
		}
		return r;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/doorbind", method = { RequestMethod.POST })
	@ApiOperation(value = "门牌或业主绑定", notes = "门牌或业主绑定信息", httpMethod = "POST")
	public String doorBindByCardAndCourt(@RequestBody VoteParam o) {
		String message = "";
		try {
			Proprietor ps = proprietorRepository.findPropriByCard(o.getCard());
			// List<Doorplate> ds =
			// doorplateRepository.loadDoorByProAndCourt(ps.getId(),
			// o.getCourtId());
			List<Doorplate> ds = doorplateRepository.loadBindDoorplate(ps.getId());
			for (Doorplate d : ds) {
				if (!d.isBing()) {
					d.setBing(true);
					d.setOpenId(o.getOpenId());
					doorplateRepository.save(d);
				}
				activeRenWu(d.getCourtId());
			}
			if (null != ps.getOpenid()) {
				logger.info("此业主已经绑定过业主信息");
				message = "此业主已经绑定过业主信息";
			} else {
				proprietorRepository.wenxinbindProprietor(o.getOpenId(), ps.getId());
				message = "success";
			}
		} catch (Exception e) {
			logger.error("门牌或业主绑定发生错误");
			message = "门牌或业主绑定发生错误";
		}
		return message;
	}

	public void activeRenWu(String courtid) {
		List<RenWu> rw = rwRepository.findRenWuLsByCourt(courtid, "CAST01");
		if (null != rw && !rw.isEmpty()) {
			RenWu r = rw.get(0);
			if (!r.isActive()) {
				Court c = courtRepository.get(courtid);
				if (null != c) {
					List<Doorplate> ds = doorplateRepository.LoadBindDoorCoundByCourt(courtid);
					if (null != ds && !ds.isEmpty()) {
						double b = (double) (Math.round(ds.size() * 100) / c.getCourtcount());
						if (b > 0.69) {
							r.setActive(true);
							Date now = new Date();
							r.setStartTime(now);
							Calendar ca = Calendar.getInstance();
							ca.add(Calendar.DATE, 7);
							r.setEndTime(ca.getTime());
							rwRepository.save(r);
							renWuCreateUnit(courtid);
							// 给小区所有人发送竞选单元长的模板消息
							List<String> list = doorplateRepository.findIsBingOpenId(courtid);
							if (!list.isEmpty()) {
								// 发送模板消息
								WxTemplateMesController wmc = new WxTemplateMesController();
								for (int i = 0; i < list.size(); i++) {
									try {
										wxService.getTemplateMsgService()
												.sendTemplateMsg(wmc.getTemplate(list.get(i), c.getName(), "报名入口",
														CalendarUtil.getDate(), "http://" + webDomain + "#/home/my",
														voteTempleteCode));
									} catch (WxErrorException e) {
										logger.error("发送模板消息失败");
										e.printStackTrace();
									}
								}
							}
						}
					}
				}
			}
		}
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void renWuCreateUnit(String courtid) {

		List<Doorplate> ds = doorplateRepository.LoadBindDoorCoundByCourt(courtid);

		Map<String, Set<String>> rwMap = new HashMap<String, Set<String>>();
		for (Doorplate d : ds) {
			if (StringUtils.isNotEmpty(d.getBuilding()) && StringUtils.isNotEmpty(d.getUnit())) {
				rwMap.put(d.getBuilding(), new HashSet());
			}
		}

		for (Doorplate d : ds) {
			rwMap.get(d.getBuilding()).add(d.getUnit());
		}
		Integer num = 0;
		if (num == rwCreateRepository.findCastCount("CAST03", courtid)) {
			RenWuCreate r = new RenWuCreate();
			r.setRwCode("CAST03");
			r.setRwName("委员");
			r.setActive(false);
			r.setCourtId(courtid);
			rwCreateRepository.save(r);
		}

		if (num == rwCreateRepository.findCastCount("CAST04", courtid)) {
			RenWuCreate r = new RenWuCreate();
			r.setRwCode("CAST04");
			r.setRwName("主任");
			r.setActive(false);
			r.setCourtId(courtid);
			rwCreateRepository.save(r);
		}

		Iterator<Map.Entry<String, Set<String>>> entries = rwMap.entrySet().iterator();
		while (entries.hasNext()) {

			Map.Entry<String, Set<String>> entry = entries.next();

			System.out.println("Key 楼栋= " + entry.getKey() + ", Value单元 = " + entry.getValue());
			if (num == rwCreateRepository.findCastCount("CAST02", courtid, entry.getKey())) {
				RenWuCreate r = new RenWuCreate();
				r.setRwCode("CAST02");
				r.setRwName("楼栋长");
				r.setActive(false);
				r.setCourtId(courtid);
				r.setBuilding(entry.getKey());
				rwCreateRepository.save(r);
			}

			for (String content : entry.getValue()) {
				System.out.println("Key 楼栋= " + entry.getKey() + ", Value单元 = " + content);
				if (num == rwCreateRepository.findCastCount("CAST01", courtid, entry.getKey(), content)) {
					RenWuCreate r = new RenWuCreate();
					r.setRwCode("CAST01");
					r.setRwName("单元长");
					r.setActive(true);
					r.setCourtId(courtid);
					r.setBuilding(entry.getKey());
					r.setUnit(content);
					rwCreateRepository.save(r);
				}
			}
		}
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/isCast", method = { RequestMethod.GET })
	@ApiOperation(value = "是否已报名", notes = "是否已报名", httpMethod = "GET")
	public boolean isCastOk(String proprietorId, String courtId, String code) {
		if ("CAST01".equals(code)) {
			return doorplateRepository.isCastUnit(proprietorId, courtId);
		} else if ("CAST02".equals(code)) {
			return doorplateRepository.isCastBuilding(proprietorId, courtId);
		} else if ("CAST03".equals(code)) {
			return doorplateRepository.isCastMember(proprietorId, courtId);
		} else if ("CAST04".equals(code)) {
			return doorplateRepository.isCastHead(proprietorId, courtId);
		} else {
			return false;
		}
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/doorCastok", method = { RequestMethod.POST })
	@ApiOperation(value = "报名", notes = "报名信息", httpMethod = "POST")
	public boolean doorCastOk(@RequestBody VoteParam o) throws MException {
		try {
			Doorplate ps = doorplateRepository.get(o.getDoorId());
			ps.setCastUnit(true);
			doorplateRepository.save(ps);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/doorCastno", method = { RequestMethod.POST })
	@ApiOperation(value = "报名", notes = "报名信息", httpMethod = "POST")
	public boolean doorCastNo(@RequestBody VoteParam o) throws MException {
		try {
			Doorplate ps = doorplateRepository.get(o.getDoorId());
			ps.setCastUnit(false);
			doorplateRepository.save(ps);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/loadDoorplateById")
	@ApiOperation(value = "业主ID获取门牌号", notes = "业主ID获取门牌号", httpMethod = "GET")
	@ApiImplicitParams({ @ApiImplicitParam(name = "proid", value = "proid", paramType = "form", dataType = "string") })
	public List<Doorplate> loadDoorplateById(@ApiIgnore DoorplateQueryParam p) {
		List<Doorplate> doors = new ArrayList<Doorplate>();
		doors = doorplateRepository.loadBindDoorplate(p.getProid());
		setCourtsName(doors);
		return doors;
	}

	public void setCourtsName(List<Doorplate> doors) {
		for (Doorplate d : doors) {
			if (StringUtils.isNotEmpty(d.getCourtId())) {
				Court c = courtRepository.get(d.getCourtId());
				if (null != c) {
					d.setCourtName(c.getName());
				}
			}
		}

	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping("/loadDoorBind")
	@ApiOperation(value = "业主ID获取绑定小区", notes = "业主ID获取绑定门牌号", httpMethod = "GET")
	@ApiImplicitParams({ @ApiImplicitParam(name = "proid", value = "proid", paramType = "form", dataType = "string") })
	public List<Doorplate> loadDoorBind(@ApiIgnore DoorplateQueryParam p) {
		List<Doorplate> doors = new ArrayList<Doorplate>();
		List<String> list = new ArrayList<String>();
		list.add(p.getProid());
		doors = doorplateRepository.searchBindDoorPropri(list);
		setCourtsName(doors);
		return doors;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping("/findPhonenByCourt")
	@ApiOperation(value = "根据电话号码获取业主id在获取小区", notes = "业主ID获取门牌号", httpMethod = "GET")
	@ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "phone", paramType = "form", dataType = "string") })
	public List<Court> findCourtByPhone(@ApiIgnore DoorplateQueryParam p) {

		List<Court> courts = new ArrayList<Court>();
		List<Proprietor> pros = new ArrayList<Proprietor>();
		List<Doorplate> doors = new ArrayList<Doorplate>();

		List<String> list = new ArrayList<String>();

		pros = proprietorRepository.findPropriByPhone(p.getPhone());
		if (pros.isEmpty()) {
			return null;
		} else {

			for (Proprietor pro : pros) {
				list.add(pro.getId());
			}

			if (!list.isEmpty()) {
				doors = doorplateRepository.searchDoorPropri(list);
				if (!doors.isEmpty()) {
					courts = findMapDoor(doors);
				}
			}

		}

		return courts;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "手动给指定小区创建任务Create", log = false)
	@RequestMapping(value = "/testAddRenWuCreate", method = { RequestMethod.GET })
	public void testAddRenWuCreate(String courtid) {
		this.renWuCreateUnit(courtid);
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "通过业主ID获取能够报名单元长的门牌号集合", log = false)
	@RequestMapping(value = "/getActiveSignUpDoorplate", method = { RequestMethod.GET })
	public List<Doorplate> getActiveSignUpDoorplate(String proprietorId) {
		List<Doorplate> list = new ArrayList<Doorplate>();
		List<String> activeCourtIdList = rwRepository.findUnitActiveRenWuByProprietorId(proprietorId);
		for (int i = 0; i < activeCourtIdList.size(); i++) {
			List<Doorplate> doorList = doorplateRepository.loadDoorByProAndCourt(proprietorId,
					activeCourtIdList.get(i));
			if (!doorList.isEmpty()) {
				for (int j = 0; j < doorList.size(); j++) {
					Doorplate d = doorList.get(j);
					if (d.getCourtId() != null) {
						Court c = courtRepository.get(d.getCourtId());
						d.setCourtName(c.getName());
					} else {
						logger.error("门牌号的小区id为空");
					}
				}
				list.addAll(doorList);
			}
		}
		return list;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "通过openId获取用户信息", log = false)
	@RequestMapping(value = "/getProprietorByOpenId", method = { RequestMethod.GET })
	public Proprietor getProprietorByOpenId(String openId) {
		return proprietorRepository.findProprietorByOpenId(openId);
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "根据openid获取全家桶", log = false)
	@RequestMapping(value = "/getinfoByOpenId", method = { RequestMethod.GET })
	public List<Doorplate> getinfoByOpenId(String openId) {
		// 根据openid获取用户信息
		List<Doorplate> list = new ArrayList<Doorplate>();
		Proprietor p = proprietorRepository.findProprietorByOpenId(openId);
		if (p != null) {
			list = doorplateRepository.loadBindDoorplate(p.getId());
			if (!list.isEmpty()) {
				for (int i = 0; i < list.size(); i++) {
					Doorplate d = list.get(i);
					if (d.getCourtId() != null) {
						Court c = courtRepository.get(d.getCourtId());
						d.setCourtName(c.getName());
						d.setProprietorName(p.getName());
					} else {
						logger.error("门牌号的小区id为空");
					}
				}
			} else {
				logger.error("根据用户id没有获取到门牌号相关信息");
			}
		} else {
			logger.error("openId没有对应的业主信息");
		}
		return list;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@ControllerLogExeTime(description = "根据proprietorId获取门牌号信息，并按小区分组", log = false)
	@RequestMapping(value = "/getDoorGroupCourt", method = { RequestMethod.GET })
	public List<CourtVO> getDoorplateGroupCourt(String proprietorId) {
		List<CourtVO> result = new ArrayList<CourtVO>();
		List<String> courtIds = doorplateRepository.getCourtIds(proprietorId);
		for (String courtId : courtIds) {
			CourtVO courtVo = new CourtVO();
			Court c = courtRepository.get(courtId);
			courtVo.setId(c.getId());
			courtVo.setName(c.getName());
			courtVo.setAddress(c.getAddress());
			courtVo.setLat(c.getLat());
			courtVo.setLng(c.getLng());
			List<DoorVO> doorVos = new ArrayList<DoorVO>();
			List<Doorplate> doors = doorplateRepository.findDoorPriproOrder(courtId, proprietorId);
			for (Doorplate door : doors) {
				DoorVO vo = new DoorVO();
				vo.setDoorId(door.getId());
				vo.setDoorNo(door.getDoorplateNo());
				vo.setUnit(door.getUnit());
				vo.setBing(door.isBing());
				vo.setBuilding(door.getBuilding());
				vo.setCastUnit(door.isCastUnit());
				vo.setCastBuilding(door.isCastBuilding());
				vo.setCastMember(door.isCastMember());
				vo.setCastHead(door.isCastHead());
				vo.setCountUnit(door.getCountUnit());
				vo.setCountBuilding(door.getCountBuilding());
				vo.setCountMember(door.getCountMember());
				vo.setCountHead(door.getCountHead());
				vo.setCourtId(door.getCourtId());
				vo.setUnitVoteDoorplateId(door.getUnitVoteDoorplateId());
				vo.setBuildingVoteDoorplateId(door.getBuildingVoteDoorplateId());
				vo.setMemberVoteDoorplateId(door.getMemberVoteDoorplateId());
				vo.setHeadVoteDoorplateId(door.getHeadVoteDoorplateId());
				vo.setOpenId(door.getOpenId());
				vo.setProprietorId(door.getProprietorId());
				vo.setRightUnit(door.isRightUnit());
				vo.setRightBuilding(door.isRightBuilding());
				vo.setRightMember(door.isRightMember());
				vo.setRightHead(door.isRightHead());
				doorVos.add(vo);
			}
			courtVo.setDoors(doorVos);
			result.add(courtVo);
		}
		return result;
	}

	public List<Court> findMapDoor(List<Doorplate> ds) {
		Map<String, Court> courtMap = new HashMap<String, Court>();
		List<Court> courts = new ArrayList<Court>();
		for (Doorplate d : ds) {
			if (StringUtils.isNotEmpty(d.getCourtId())) {
				Court c = courtRepository.get(d.getCourtId());
				if (null != c) {
					d.setCourtName(c.getName());
					courtMap.put(d.getCourtId(), c);

				}
			}
		}
		for (String c : courtMap.keySet()) {
			courts.add(courtMap.get(c));
		}

		return courts;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/loadCourtById")
	@ApiOperation(value = "业主ID获取小区", notes = "业主ID获取门牌号", httpMethod = "GET")
	@ApiImplicitParams({ @ApiImplicitParam(name = "proid", value = "proid", paramType = "form", dataType = "string") })
	public List<Court> loadCourtById(@ApiIgnore DoorplateQueryParam p) {
		List<Doorplate> doors = new ArrayList<Doorplate>();
		List<Court> courts = new ArrayList<Court>();
		doors = doorplateRepository.loadBindDoorplate(p.getProid());
		courts = findMapDoor(doors);
		return courts;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/TestGetBuilding", method = { RequestMethod.GET })
	@ApiOperation(value = "测试", notes = "测试groupby", httpMethod = "GET")
	public void TestGetBuilding(VoteParam o) throws MException {
		List<String> bulidingList = doorplateRepository.groupByBuilding("c75ee0dd-719c-4f00-9912-f602f49b3084");
		for (int i = 0; i < bulidingList.size(); i++) {
			String building = bulidingList.get(i);
			System.out.println(building);
			List<String> unitList = doorplateRepository.groupByUnit("c75ee0dd-719c-4f00-9912-f602f49b3084", building);
			for (int j = 0; j < unitList.size(); j++) {
				String unit = unitList.get(j);
				System.out.println(unit);
				// doorplateRepository
				List<Doorplate> list = doorplateRepository.findMaxUnitVotes("c75ee0dd-719c-4f00-9912-f602f49b3084",
						unit, building);
				if (!list.isEmpty()) {
					System.out.println("list有值");
					if (list.size() > 1) {
						logger.info("出现" + list.size() + "个相同票数，取第一个候选人为单元长");
					}
					Doorplate dp = list.get(0);
					CourtRole cr = courtRoleRepository.findCourtRoleByName("单元长");
					CourtRole_Proprietor crpr = new CourtRole_Proprietor();
					crpr.setDoorPlateId(dp.getId());
					crpr.setRoleId(cr.getId());
					crpr.setCourtId(dp.getCourtId());
					crpr.setRoleName("单元长");
					// 先去查询数据库中是否已经存在相同的记录
					CourtRole_Proprietor cpr = courtRoleBindRepository.findCourtRoleByName(dp.getId(), cr.getId());
					if (cpr != null) {
						logger.error("数据库中存在相同门牌号和角色的记录");
					} else {
						courtRoleBindRepository.save(crpr);
					}
				}
			}
		}
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/findDoorInfoById")
	@ApiOperation(value = "doorID获取门牌号信息和小区信息", httpMethod = "GET")
	public DoorInfo findDoorInfoById(String id) {
		DoorInfo rtn = new DoorInfo();
		Doorplate door = doorplateRepository.get(id);
		if (door != null) {
			rtn.setDoorId(id);
			rtn.setDoorNo(door.getDoorplateNo());
			rtn.setBuilding(door.getBuilding());
			rtn.setUnit(door.getUnit());
			rtn.setCourtId(door.getCourtId());
			Court c = courtRepository.get(door.getCourtId());
			if (c != null) {
				rtn.setCourtName(c.getName());
			}
		}
		return rtn;
	}

	@CrossOrigin(origins = "*", maxAge = 3600)
	@RequestMapping(value = "/findCountDoorByCourtId")
	@ApiOperation(value = "获取楼栋单元户数", httpMethod = "GET")
	public Page<YwhSettingsJQTreeNode> findCountDoorByCourtId(String courtId) {
		List<DoorCount> rtn = new ArrayList<DoorCount>();
		List<CourtYwhSettings> entities = courtYwhSettingsRepository.findAllByCourtId(courtId);
		if (entities == null || entities.size() == 0) {
			List<Object[]> rs = doorplateRepository.findCountDoorByCourtId(courtId);
			if (rs != null && rs.size() > 0) {
				String building = null;
				int totalDoors = 0;
				List<DoorCount> tempDCs = new ArrayList<DoorCount>();
				DoorCount doorCountOfBuilding = null;
				for (Object[] o : rs) {
					DoorCount dc = new DoorCount();
					dc.setCountOfUnit(Integer.valueOf(String.valueOf(o[0])));
					dc.setCourtId(String.valueOf(o[1]));
					dc.setBuilding(String.valueOf(o[2]));
					dc.setUnit(String.valueOf(o[3]));

					if (building == null) {
						tempDCs.add(dc);
						building = dc.getBuilding();
						totalDoors = dc.getCountOfUnit();
					} else {
						if (building.equals(dc.getBuilding())) {
							totalDoors = totalDoors + dc.getCountOfUnit();
							tempDCs.add(dc);
						} else {
							doorCountOfBuilding = new DoorCount();
							doorCountOfBuilding.setBuilding(building);
							doorCountOfBuilding.setCountOfBuilding(totalDoors);
							doorCountOfBuilding.setCourtId(dc.getCourtId());
							rtn.add(doorCountOfBuilding);
							for (DoorCount dcTemp : tempDCs) {
								rtn.add(dcTemp);
							}
							tempDCs.clear();
							building = dc.getBuilding();
							totalDoors = dc.getCountOfUnit();
							tempDCs.add(dc);
						}
					}
				}
				if (tempDCs.size() > 0) {
					doorCountOfBuilding = new DoorCount();
					doorCountOfBuilding.setBuilding(building);
					doorCountOfBuilding.setCountOfBuilding(totalDoors);
					doorCountOfBuilding.setCourtId(courtId);
					rtn.add(doorCountOfBuilding);
					for (DoorCount dcTemp : tempDCs) {
						rtn.add(dcTemp);
					}
					tempDCs.clear();
				}
				String parentId = null;
				for (DoorCount dc : rtn) {
					CourtYwhSettings entity = new CourtYwhSettings();
					entity.setCourtId(dc.getCourtId());
					entity.setBuilding(dc.getBuilding());
					entity.setUnit(dc.getUnit());
					if (parentId != null && dc.getUnit() != null) {
						entity.setParentId(parentId);
					}
					if (dc.getUnit() == null) {
						entity.setTotalDoors(dc.getCountOfBuilding());
						entity.setType("B");
					} else {
						entity.setTotalDoors(dc.getCountOfUnit());
						entity.setType("U");
					}
					courtYwhSettingsRepository.save(entity);
					if (dc.getUnit() == null) {
						parentId = entity.getId();
					}
				}
				entities = courtYwhSettingsRepository.findAllByCourtId(courtId);
			}
		}

		List<YwhSettingsJQTreeNode> nodes = buildJQTreeNode(entities);
		Page<YwhSettingsJQTreeNode> page = new PageImpl<YwhSettingsJQTreeNode>(nodes);

		return page;
	}

	@SuppressWarnings("rawtypes")
	private List<YwhSettingsJQTreeNode> buildJQTreeNode(List<CourtYwhSettings> list) {

		List<YwhSettingsJQTreeNode> nodes = null;
		if (list != null) {
			nodes = new ArrayList<YwhSettingsJQTreeNode>();
			Map<String, YwhSettingsJQTreeNode> map = new HashMap<String, YwhSettingsJQTreeNode>();
			for (CourtYwhSettings entity : list) {
				YwhSettingsJQTreeNode node = new YwhSettingsJQTreeNode();
				String parentId = entity.getParentId();
				node.setId(entity.getId());
				node.setParentId(parentId);
				node.setParent(parentId);
				node.setBuilding(entity.getBuilding());
				node.setUnit(entity.getUnit());
				node.setCountMember(entity.getCountMember());
				node.setTotalDoors(entity.getTotalDoors());
				node.setType(entity.getType());
				node.setIsLeaf(true);

				map.put(node.getId(), node);
				nodes.add(node);
			}
			Collection<YwhSettingsJQTreeNode> values = map.values();
			for (YwhSettingsJQTreeNode node : values) {
				String parentId = node.getParentId();
				String tempParentId = parentId;
				int level = 0;
				while (StringUtils.isNotEmpty(tempParentId)) {
					YwhSettingsJQTreeNode temp = map.get(tempParentId);
					temp.setIsLeaf(false);
					if (temp != null) {
						level++;
						tempParentId = temp.getParentId();
					}
				}
				node.setLevel(level);
			}

			List<TreeNode> treeList = TreeUtil.build(list);
			List<YwhSettingsJQTreeNode> result = new ArrayList<YwhSettingsJQTreeNode>();
			iterator(treeList, result, map);
			return result;

		}
		return null;
	}

	@SuppressWarnings({ "rawtypes" })
	private void iterator(List<? extends TreeNode> list, List<YwhSettingsJQTreeNode> result,
			Map<String, YwhSettingsJQTreeNode> map) {

		if (list != null && !list.isEmpty()) {
			for (TreeNode tree : list) {
				String id = tree.getId();
				YwhSettingsJQTreeNode ywhSettingsJQTreeNode = map.get(id);
				result.add(ywhSettingsJQTreeNode);
				@SuppressWarnings("unchecked")
				List<TreeNode> children = tree.getChildren();
				if (children != null && !list.isEmpty()) {
					iterator(children, result, map);
				}
			}
		}
	}

	public List<String> toList(String value, String separator) {
		List<String> result = new ArrayList<String>();
		if (!this.isEmpty(value)) {
			String[] as = value.split(separator);
			for (int i = 0; i < as.length; i++) {
				result.add(as[i]);
			}
		}
		return result;
	}

	public boolean isEmpty(String str) {
		return str == null || str.length() == 0;
	}

	public String sfzplus(String str, Integer StartLen, Integer endLen) {
		Integer len = str.length() - StartLen - endLen;
		String xing = "";
		for (int i = 0; i < len; i++) {
			xing += '*';
		}

		String sfz = str.substring(0, StartLen) + xing + str.substring(str.length() - endLen);

		return sfz;
	}

}
